//
//  PackageChecker.m
//  gdemm
//
//  Created by 乔明超 on 16/10/28.
//  Copyright © 2016年 Goldencis. All rights reserved.
//

#import "PackagesChecker.h"
#import "PackageInfo.h"
#import "ExamineManager.h"
#import <objc/runtime.h>
@interface PackagesChecker()
{
    BOOL _mBlackMode;
    BOOL _mIslegal;
    
}
//存放检测规则package的集合
@property(strong,nonatomic)NSMutableArray *mPackList;
//存放非法应用package的集合
@property(strong,nonatomic)NSMutableArray *mIllegalList;
//存放合法应用package的集合
@property(strong,nonatomic)NSMutableArray *legalPackageList;
@end
@implementation PackagesChecker

- (instancetype)init
{
    self = [super init];
    if (self) {
        _mBlackMode = YES;
        _mIslegal = YES;
    }
    return self;
}
static PackagesChecker *mInstance;

- (NSMutableArray *)mPackList{
    if (_mPackList == nil) {
        _mPackList = [NSMutableArray array];
    }
    return _mPackList;
}

- (NSMutableArray *)mIllegalList{
    if (_mIllegalList == nil) {
        _mIllegalList = [NSMutableArray array];
    }
    return _mIllegalList;
}

- (NSMutableArray *)legalPackageList
{
    if (_legalPackageList == nil)
    {
        _legalPackageList = [NSMutableArray array];
    }
    return _legalPackageList;
}

+ (instancetype)getInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mInstance = [[self alloc]init];
    });
    return mInstance;
    
}

//重写父类的方法
- (NSString *)getExamineDesc{
    return @"应用安全检测";
}
//获取修复类型,自动修复
- (NSInteger)getRepairType{
    return RT_AUTO;
}
- (BOOL)run{
    [self.mIllegalList removeAllObjects];
    NSMutableArray *apps = [self getAllAppsFromDevice];
    for (PackageInfo *packageInfo in apps) {
        if (self.mPackList.count == 0) {
            break;
        }
        BOOL bIllegal = NO; //是否为非法应用
        NSString *packageName = packageInfo.packageName;
//        NSString *tmpName = [packageName lowercaseString];
        //比较当前包名是不是自己,如果是,跳过
        if ([packageInfo.packageName isEqualToString:@"cn.neiwang.emm"]||[packageInfo.packageName isEqualToString:@"cn.neiwang.gview"]) {
            continue;
        }
        
        //获取应用的名字
        NSString *softName = packageInfo.softName;
        
        //如果是黑名单模式
        if (_mBlackMode) {
            bIllegal = NO;
            for (NSString *item in self.mPackList) {
                if ([item containsString:@"*"]) {
                    NSString *tmpItem = [[item stringByReplacingOccurrencesOfString:@"*" withString:@""]lowercaseString];
                    if ([[softName lowercaseString] containsString:tmpItem] || (softName != nil && [[softName lowercaseString]isEqualToString:tmpItem])) {
                        bIllegal = YES;
                        break;
                    }
                }else{
                
                    NSString *tmpItem = [item lowercaseString];
                    if ([[softName lowercaseString] containsString:tmpItem] || (softName != nil && [[softName lowercaseString]isEqualToString:tmpItem])) {
                        bIllegal = YES;
                        break;
                    }
                    
                }
            }
            
        }else{//如果是白名单模式
            bIllegal = YES;
            for (NSString *item in self.mPackList) {
                if ([item containsString:@"*"]) {
                    NSString *tmpItem = [[item stringByReplacingOccurrencesOfString:@"*" withString:@""]lowercaseString];
                    if ([[softName lowercaseString] containsString:tmpItem] || (softName != nil && [[softName lowercaseString]isEqualToString:tmpItem])) {
                        bIllegal = NO;
                        break;
                    }
                }else{
                
                    NSString *tmpItem = [item lowercaseString];
                    if ([[softName lowercaseString] containsString:tmpItem] || (softName != nil && [[softName lowercaseString]isEqualToString:tmpItem])) {
                        bIllegal = NO;
                        break;
                    }
                    
                }
            }
        
        }
        if (bIllegal) {
            [self.mIllegalList addObject:softName];
            [NSThread sleepForTimeInterval:0.2];
            [self reportExamineInfo:[NSString stringWithFormat:@"PackageCheck&%@&0",softName]];
        }
        
    }
    
    if (self.mIllegalList.count == 0) {
        [[ExamineManager getInstance].examineResult setObject:@1 forKey:EXAMINE_PACKAGE_STATUS_TAG];
        [self reportExamineInfo:[NSString stringWithFormat:@"PackageCheck&%@&0",@""]];
    }else{
        
        NSMutableString *info = [NSMutableString stringWithString:@"发现以下违规应用:"];
        [self.mIllegalList enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [info appendString:[NSString stringWithFormat:@"%@;",obj]];           
        }];
        [info deleteCharactersInRange:NSMakeRange(info.length-1, 1)];
        [[ExamineManager getInstance].examineResult setObject:info forKey:EXAMINE_PACKAGE_STATUS_TAG];
    }
    _mIslegal = self.mIllegalList.count == 0;
    return _mIslegal;
}

#pragma mark -- 安全桌面显示的应用

- (NSMutableArray *)getLagalPackageList
{
    [self.legalPackageList removeAllObjects];
    NSMutableArray *apps = [self getAllAppsFromDevice];
    NSMutableArray *appPackageArr = [[NSMutableArray alloc] initWithArray:apps];
    for (PackageInfo *packageInfo in apps){
        if (self.mPackList.count == 0) {
            return apps;
        }
        BOOL bIllegal = NO; //是否为非法应用
        //获取应用的名字
        NSString *softName = packageInfo.softName;
        
        //如果是黑名单模式
        if (_mBlackMode) {
            bIllegal = NO;
           
            for (NSString *item in self.mPackList) {
                if ([item containsString:@"*"]) {
                    NSString *tmpItem = [[item stringByReplacingOccurrencesOfString:@"*" withString:@""]lowercaseString];
                    if ([[softName lowercaseString] containsString:tmpItem] || (softName != nil && [[softName lowercaseString]isEqualToString:tmpItem])) {
                        bIllegal = YES;
                        break;
                    }
                }else{
                    
                    NSString *tmpItem = [item lowercaseString];
                    if ([[softName lowercaseString] containsString:tmpItem] || (softName != nil && [[softName lowercaseString]isEqualToString:tmpItem])) {
                        bIllegal = YES;
                        break;
                    }
                    
                }
            }
            
        }else{//如果是白名单模式
            bIllegal = YES;
            
            if ([packageInfo.packageName isEqualToString:@"cn.neiwang.gview"]) {
                [self.legalPackageList addObject:packageInfo];
            }
            for (NSString *item in self.mPackList) {
                if ([item containsString:@"*"]) {
                    NSString *tmpItem = [[item stringByReplacingOccurrencesOfString:@"*" withString:@""]lowercaseString];
                    if ([[softName lowercaseString] containsString:tmpItem] || (softName != nil && [[softName lowercaseString]isEqualToString:tmpItem])) {
                        bIllegal = NO;
                        break;
                    }
                }else{
                    
                    NSString *tmpItem = [item lowercaseString];
                    if ([[softName lowercaseString] containsString:tmpItem] || (softName != nil && [[softName lowercaseString]isEqualToString:tmpItem])) {
                        bIllegal = NO;
                        break;
                    }
                    
                }
            }
            
        }
        if (bIllegal == NO)
        {
          

            [self.legalPackageList addObject:packageInfo];
           
        }
        else if (bIllegal == YES && _mBlackMode)
        {
            
            [appPackageArr removeObject:packageInfo];
        }
        

    }
    if (_mBlackMode)
    {
        return appPackageArr;
    }
    else
    {
        return self.legalPackageList;
    }
    return nil;
}

- (id)details{
    return self.mIllegalList;
}

- (BOOL)returnValue{
    return _mIslegal;
}

//修复危险项
- (BOOL)repair{
    return NO;
}


/**
 *解析检测规则,并获取黑白名单应用数据
 *@param content
 */
- (void)getExamineContent:(NSDictionary *)content{
    if (self.mPackList.count > 0) {
        [self.mPackList removeAllObjects];
    }
    NSString *mode = content[CHECK_APP_OR_WLAN_MODE];
    if ([mode isEqualToString:CHECK_APP_OR_WLAN_MODE_BLACK]) {
        _mBlackMode = YES;
    }else{
        _mBlackMode = NO;
    }
    NSString *key = _mBlackMode?CHECK_APP_OR_WLAN_MODE_BLACKTAG : CHECK_APP_OR_WLAN_MODE_WHITETAG;
    self.mPackList = content[key];
}


- (NSInteger)getExamineContentCount{
    return [[self getAllAppsFromDevice]count];;
}


- (void)reset{
    if (self.mPackList.count > 0) {
        [self.mPackList removeAllObjects];
    }
    [self.mIllegalList removeAllObjects];
    [self.legalPackageList removeAllObjects];
}


//获取用户安装的app信息
- (NSMutableArray *)getAllAppsFromDevice
{
    
    
    NSMutableArray *app = [NSMutableArray array];
    //获取手机上所有的app
    Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
    NSObject *workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];
    NSArray *apps = [workspace performSelector:@selector(allInstalledApplications)];
    Class LSApplicationProxy_class = objc_getClass("LSApplicationProxy");
    for (int i = 0; i < apps.count; i++) {
        NSObject *temp = apps[i];
        if ([temp isKindOfClass:LSApplicationProxy_class]) {
            NSString *appBundleId = [temp performSelector:NSSelectorFromString(@"applicationIdentifier")];
            NSString *appName = [temp performSelector:NSSelectorFromString(@"localizedName")];
            
            NSString *appVersion = [temp performSelector:NSSelectorFromString(@"shortVersionString")];
            NSInteger appSize = [temp performSelector:NSSelectorFromString(@"description")];
            NSString * type = [temp performSelector:NSSelectorFromString(@"applicationType")];
            
            if ([type isEqualToString:@"User"] && ![appBundleId isEqualToString:@"cn.neiwang.emm"]) {
                PackageInfo *packageInfo = [[PackageInfo alloc]init];
                packageInfo.softName = appName;
                packageInfo.packageName = appBundleId;
                packageInfo.iconImage = [self iconImage:temp];
                packageInfo.version = appVersion;
                packageInfo.size = 0;
                [app addObject:packageInfo];
            }
        }
    }
    
    
    return app;
    
}

- (UIImage *)iconImage:(id)app
{
    
    NSData *iconData = [app performSelector:NSSelectorFromString(@"iconDataForVariant:") withObject:@(2)];
#pragma clang diagnostic pop
    
    NSInteger lenth = iconData.length;
    NSInteger width = 87;
    NSInteger height = 87;
    
    uint32_t *pixels = (uint32_t *)malloc(width * height * sizeof(uint32_t));
    [iconData getBytes:pixels range:NSMakeRange(32, lenth - 32)];
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(pixels,
                                             width,
                                             height,
                                             8,
                                             (width + 1) * sizeof(uint32_t),
                                             colorSpace,
                                             kCGBitmapByteOrder32Little |
                                             kCGImageAlphaPremultipliedFirst);
    
    CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    UIImage *icon = [UIImage imageWithCGImage: cgImage];
    CGImageRelease(cgImage);
    
    return icon;
}



@end
